/**
 * 
 */
package org.t2.game.server.module.data.saver;

import java.lang.reflect.ParameterizedType;

import org.gaming.service.repository.IRepository;
import org.gaming.service.repository.Repository;

import sh.t2.share.module.player.log.PlayerNumberLog;

/**
 * 
 */
public abstract class AbstractPlayerSaver<T extends IPlayerData, Log extends PlayerNumberLog> {
	protected final Class<Log> logClazz;
	private IRepository<Log> logRepository;
	
	@SuppressWarnings("unchecked")
	public AbstractPlayerSaver() {
		Class<?> currClz = this.getClass();
		Class<Log> logClazz = null;
		while(currClz != null) {
			if(currClz.getGenericSuperclass() instanceof ParameterizedType) {
				ParameterizedType ptype = (ParameterizedType)currClz.getGenericSuperclass();
				if(ptype.getActualTypeArguments().length == 2) {
					logClazz = (Class<Log>) ptype.getActualTypeArguments()[1];
					break;
				}
			}
			currClz = currClz.getSuperclass();
		}
		this.logClazz = logClazz;
	}
	
	protected final IRepository<Log> logRepository() {
		if(logRepository == null) {
			logRepository = Repository.get(logClazz);
		}
		return logRepository;
	}
	
	
	protected abstract Log newNumberLog();
	
	public abstract long getNumber(T t);
	
	public final void setNumber(T t, String reason, long number) {
		long oriNumber = getNumber(t);
		setNumber0(t, number);
		
		Log log = newNumberLog();
		log.setPlayerId(t.getPlayerId());
		log.setCurr(number);
		log.setDelta(number - oriNumber);
		log.setReason(reason);
		this.logRepository().insert(log);
	}
	
	protected abstract void setNumber0(T t, long number);
}
